﻿#region Namespaces

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;

using Vibstudio.X4NET.IO;
using Vibstudio.X4NET.IO.Path;

using Newtonsoft.Json.Linq;

#endregion

namespace Vibstudio.X4NET.Globalization
{
    public class JsonLabelingProvider : LabelingProviderBase, ILabelingProvider
    {
        private const string DEFAULT_LANG_FILE_NAME = "lang.json";

        public JsonLabelingProvider()
            : this(string.Empty)
        {
        }

        protected JsonLabelingProvider(string lang = "", string langFileName = "", string appLangKey = "")
        {
            AppLang = lang;
            AppLangFileName = string.IsNullOrEmpty(langFileName) ? DEFAULT_LANG_FILE_NAME : langFileName;
            AppLangKey = string.IsNullOrEmpty(appLangKey) ? DefaultAppLangKey : appLangKey;
        }

        protected IDictionary<string, List<DictionaryEntry>> LabelDictionary()
        {
            IDictionary<string, List<DictionaryEntry>> dictionary = new Dictionary<string, List<DictionaryEntry>>();

            try
            {
                JToken jToken = JObject.Parse(JsonText).SelectToken("labels");
                Dictionary<string, Dictionary<string, string>> jDictionary = jToken.ToObject<Dictionary<string, Dictionary<string, string>>>();

                foreach (KeyValuePair<string, Dictionary<string, string>> keyValuePair in jDictionary)
                {
                    foreach (KeyValuePair<string, string> subKeyValuePair in keyValuePair.Value)
                    {
                        string lang = subKeyValuePair.Key;

                        if (!dictionary.ContainsKey(lang))
                        {
                            dictionary.Add(lang, new List<DictionaryEntry> { new DictionaryEntry(keyValuePair.Key, subKeyValuePair.Value) });
                        }
                        else
                        {
                            dictionary[lang].Add(new DictionaryEntry(keyValuePair.Key, subKeyValuePair.Value));
                        }
                    }
                }
            }
            catch (Exception exception)
            {
                Trace.WriteLine(string.Format("Exception: {0}", exception), "JsonLabelingProvider.LabelDictionary");
            }

            return dictionary;
        }

        public IList<DictionaryEntry> LabelDictionary(string lang)
        {
            List<DictionaryEntry> dictionary = new List<DictionaryEntry>();

            try
            {
                if (string.IsNullOrEmpty(lang))
                {
                    foreach (KeyValuePair<string, List<DictionaryEntry>> keyValuePair in LabelDictionary())
                    {
                        dictionary.AddRange(keyValuePair.Value);
                    }
                }
                else
                {
                    lang = lang.ToUpper();
                    LabelDictionary().TryGetValue(lang, out dictionary);
                    if (dictionary == null)
                    {
                        lang = lang.ToLower();
                        LabelDictionary().TryGetValue(lang, out dictionary);
                    }
                }
            }
            catch (Exception exception)
            {
                Trace.WriteLine(string.Format("Exception: {0}", exception), "JsonLabelingProvider.LabelDictionary");
            }

            return dictionary;
        }

        public virtual string this[string name, string lang = ""]
        {
            get
            {
                try
                {
                    lang = string.IsNullOrEmpty(lang) ? AppLang : lang;
                    lang = lang.ToUpper();

                    string label = (string)JObject.Parse(JsonText)["labels"][name][lang];

                    if (string.IsNullOrEmpty(label))
                    {
                        lang = lang.ToLower();
                        label = (string)JObject.Parse(JsonText)["labels"][name][lang];
                    }

                    return label;
                }
                catch (Exception exception)
                {
                    Trace.WriteLine(string.Format("Exception: {0}", exception), "JsonLabelingProvider.this");
                    return string.Empty;
                }
            }
        }

        protected string JsonText
        {
            get
            {
                FilePath filePath = FilePath.Create(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, AppLangFileName));
                if (!filePath.Exists)
                {
                    filePath = FilePath.Create(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "bin", AppLangFileName));
                }

                return filePath.ToText();
            }
        }
    }
}